#include <QtGui>
#include <string>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "../app/toolbox2.h"
#include <QtDebug>
#include <QThread>
#include <qinputdialog.h>
#include "rtagdialog.h"
Toolbox2 * t;

#define DEBUG

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //t=new Toolbox2();

#ifdef DEBUG
    ui->lineEdit_MonomerFile->setText("C:/Users/chrisbun/Documents/workspace/miip/gui/a_mono.fasta");
    ui->lineEdit_SequenceFile->setText("C:/Users/chrisbun/Documents/workspace/miip/gui/AF254982.fasta");
    ui->lineEditOutputFile->setText("Test");

    ui->lineEdit_SequenceFile_2->setText("/home/chris/Dropbox/Research/MiIP/TestSequences/AF254982.fasta");
    ui->lineEditOutputFile_2->setText("TestDisc");
#endif

    //! [signal slots - whole window]
    connect(ui->tabWidget, SIGNAL(currentChanged(int)), this,
                SLOT(onChangeTab(int)));

    //! [signal slots - mono search]
    connect(ui->pushButton_OpenMonoFile, SIGNAL(clicked()), this,
                SLOT(openMonoFile()));
    connect(ui->pushButton_OpenSeqFile, SIGNAL(clicked()), this,
                SLOT(openSeqFile()));
    connect(ui->pushButton_OpenOutfile, SIGNAL(clicked()), this,
                SLOT(openOutputFile()));
    connect(ui->pushButton_StartMonoSearch, SIGNAL(clicked()), this,
                SLOT(startCalc()));
    connect(ui->lineEdit_MonomerFile, SIGNAL(textChanged(QString)), this,
                SLOT(update()));
    connect(ui->lineEdit_SequenceFile, SIGNAL(textChanged(QString)), this,
                SLOT(update()));
    connect(ui->lineEditOutputFile, SIGNAL(textChanged(QString)), this,
                SLOT(update()));
    connect(ui->horizontalSlider_Threshold, SIGNAL(valueChanged(int)), this,
                SLOT(setSpinBox(int)));
    connect(ui->spinBox_Threshold, SIGNAL(valueChanged(int)), this,
                SLOT(setSlider(int)));

    //! [signal slots - mono discovery]
    connect(ui->pushButton_OpenSeqFile_2, SIGNAL(clicked()), this,
                SLOT(openSeqFile()));
    connect(ui->pushButton_OpenOutfile_2, SIGNAL(clicked()), this,
                SLOT(openOutputFile()));
    connect(ui->pushButton_StartMonoDiscovery, SIGNAL(clicked()), this,
                SLOT(startCalc()));
    connect(ui->lineEdit_SequenceFile_2, SIGNAL(textChanged(QString)), this,
                SLOT(update()));
    connect(ui->lineEditOutputFile_2, SIGNAL(textChanged(QString)), this,
                SLOT(update()));
    connect(ui->horizontalSlider_Threshold_2, SIGNAL(valueChanged(int)), this,
                SLOT(setSpinBox(int)));
    connect(ui->spinBox_Threshold_2, SIGNAL(valueChanged(int)), this,
                SLOT(setSlider(int)));




    future = new QFuture<void>;
    watcher = new QFutureWatcher<void>;

    connect(watcher, SIGNAL(finished()), this, SLOT(monoSearchDialog()));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::exitProgram()
{
    exit(0);
}

void MainWindow::openMonoFile()
{
    monoFileName = QFileDialog::getOpenFileName(this);
    if (!monoFileName.isNull()){
        ui->lineEdit_MonomerFile->setText(monoFileName);
        ui->lineEdit_SequenceFile->setEnabled(true);
        ui->pushButton_OpenSeqFile->setEnabled(true);
    }
}

void MainWindow::openSeqFile()
{
    seqFileName = QFileDialog::getOpenFileName(this);
    if (!seqFileName.isNull()) {
        if (runMode == 0) {
            ui->lineEdit_SequenceFile->setText(seqFileName);
        }
        if (runMode == 1) {
            ui->lineEdit_SequenceFile_2->setText(seqFileName);
        }
    }
}

void MainWindow::openOutputFile()
{
    outFileName = QFileDialog::getSaveFileName(this);
    if (!outFileName.isNull()) {
        if (runMode == 0) {
            ui->lineEditOutputFile->setText(outFileName);
        }
        if (runMode == 1) {
            qDebug() << "set";
            ui->lineEditOutputFile_2->setText(outFileName);
        }
    }
}

void MainWindow::startCalc(){

    char *monoFileChar = new char[500];
    char *seqFileChar = new char[500];
    char *outFileChar = new char[500];
    float score_m, score_mm, score_gs, score_gm;
    int th, mono_min, mono_max;

    t=new Toolbox2();

    connect(t, SIGNAL(calculationStarted()), this,
                SLOT(monoSearchDialog()));
    connect(t, SIGNAL(calculationFinished()), this,
                SLOT(monoSearchDialogFinished()));
    connect(t, SIGNAL(statusMessage(QString)), this,
                SLOT(updateStatus(QString)));
    connect(t, SIGNAL(resultsTag(QString)), this,
                SLOT(setResultsTag(QString)));

    if (runMode == 0) {
    //! Pulling elements from GUI line inputs
        strcpy(monoFileChar, (char *)ui->lineEdit_MonomerFile->text().toStdString().c_str());
        strcpy(seqFileChar, (char *)ui->lineEdit_SequenceFile->text().toStdString().c_str());
        strcpy(outFileChar, (char *)ui->lineEditOutputFile->text().toStdString().c_str());
        score_m = ui->doubleSpinBox_match->text().toFloat();
        score_mm = ui->doubleSpinBox_mismatch->text().toFloat();
        score_gs = ui->doubleSpinBox_gapSeq->text().toFloat();
        score_gm = ui->doubleSpinBox_gapMono->text().toFloat();
        th = (int)ui->horizontalSlider_Threshold->value();
        t->buffer = ui->spinBox_overlap->text().toInt();

        t->set_mono_search_params(monoFileChar, seqFileChar, outFileChar, th);
        ui->pushButton_StartMonoSearch->setEnabled(false);
    }
    else if (runMode == 1) {
        strcpy(seqFileChar, (char *)ui->lineEdit_SequenceFile_2->text().toStdString().c_str());
        strcpy(outFileChar, (char *)ui->lineEditOutputFile_2->text().toStdString().c_str());
        score_m = ui->doubleSpinBox_match_2->text().toFloat();
        score_mm = ui->doubleSpinBox_mismatch_2->text().toFloat();
        score_gs = ui->doubleSpinBox_gapSeq_2->text().toFloat();
        score_gm = ui->doubleSpinBox_gapMono_2->text().toFloat();
        mono_min = ui->spinBox_monoMin->text().toInt();
        mono_max = ui->spinBox_monoMax->text().toInt();
        th = (int)ui->horizontalSlider_Threshold_2->value();
        t->buffer = ui->spinBox_overlap_2->text().toInt();

        t->set_mono_discovery_params(seqFileChar, outFileChar, th, mono_min, mono_max);
        ui->pushButton_StartMonoDiscovery->setEnabled(false);
    }

#ifdef DEBUG
    qDebug() << "Monomer file: " << monoFileChar;
    qDebug() << "Sequence file: " << seqFileChar;
    qDebug() << "Output file: " << outFileChar;
    qDebug() << "Run mode: " << runMode;
    qDebug() << "Threshold: " << th;
    qDebug() << "Buffer: " << t->buffer;
    qDebug() << "Setting value: " << score_m;
    qDebug() << "Setting value: " << score_mm;
    qDebug() << "Setting value: " << score_gs;
    qDebug() << "Setting value: " << score_gm;
#endif


    t->set_run_mode(runMode);
    qDebug() << "matrix";
    t->set_matrix_values(score_m, score_mm, score_gs, score_gm);
    qDebug() << "start";
    t->start();

}

void MainWindow::startMonoDiscovery() {

}

void MainWindow::update(){
    //! Check if Run button should be enabled
    if (runMode == 0) {
        if (!ui->lineEdit_MonomerFile->text().isEmpty()
            && !ui->lineEdit_SequenceFile->text().isEmpty()
            && !ui->lineEditOutputFile->text().isEmpty()){
            ui->pushButton_StartMonoSearch->setEnabled(true);
        }
        else {
            ui->pushButton_StartMonoSearch->setEnabled(false);
        }
    }
    if (runMode == 1) {
        if (!ui->lineEdit_SequenceFile_2->text().isEmpty()
            && !ui->lineEditOutputFile_2->text().isEmpty()){
            ui->pushButton_StartMonoDiscovery->setEnabled(true);
        }
        else {
            ui->pushButton_StartMonoDiscovery->setEnabled(false);
        }
    }
}

void MainWindow::monoSearchDialog()
{
#ifdef DEBUG
    qDebug() << "monoSearchDialog() started!";
#endif

}

void MainWindow::monoSearchDialogFinished()
{
#ifdef DEBUG
    qDebug() << "monoSearchDialog() finished!";
#endif
    ui->lineEditOutputFile->setText("");
    disconnect(t,0,0,0);
    t = NULL;
    ui->pushButton_StartMonoSearch->setEnabled(true);
    ui->pushButton_StartMonoDiscovery->setEnabled(true);


}

void MainWindow::updateStatus(QString status)
{
    ui->statusBar->showMessage(status);
}

void MainWindow::setResultsTag(QString rTag)
{
    RTagDialog *rtdialog = new RTagDialog;
    connect(rtdialog, SIGNAL(acceptTag(QString)), this,
                SLOT(setResultsTagString(QString)));
    rtdialog->show();
    rtdialog->setText(rTag);
}

void MainWindow::setResultsTagString(QString rTag)
{

    qDebug() << "setResultsTagString";
    strcpy(t->header,(char *)rTag.toStdString().c_str());
    t->unpauseThread();

}

void MainWindow::setSpinBox(int value)
{
    if (runMode == 0) {
        ui->spinBox_Threshold->setValue(value);
    }
    if (runMode == 1) {
        ui->spinBox_Threshold_2->setValue(value);
    }
}

void MainWindow::setSlider(int value)
{
    if (runMode == 0) {
        ui->horizontalSlider_Threshold->setValue(value);
    }
    if (runMode == 1) {
        ui->horizontalSlider_Threshold_2->setValue(value);
    }
}

void MainWindow::onChangeTab(int tabNum) {
    if (tabNum == 0) {
        setWindowTitle(tr("MiIP - Main"));
    }
    if (tabNum == 1) {
        setWindowTitle(tr("MiIP - Monomer Search"));
        runMode = 0;
#ifdef DEBUG
        qDebug() << "Run mode set to " << runMode;
#endif
    }
    if (tabNum == 2) {
        setWindowTitle(tr("MiIP - Monomer Discovery"));
        runMode = 1;
#ifdef DEBUG
        qDebug() << "Run mode set to " << runMode;
#endif
    }
}


